package com.qf.service.impl;

import com.qf.constant.AppConstant;
import com.qf.entity.AppCategory;
import com.qf.enums.AppEnum;
import com.qf.exception.AppException;
import com.qf.mapper.AppCategoryMapper;
import com.qf.service.AppCategoryService;
import com.qf.vo.AppCategoryVO;
import com.qf.vo.EasyUITreeVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class AppCategoryServiceImpl implements AppCategoryService {

    @Resource
    private AppCategoryMapper appCategoryMapper;

    @Override
    public List<AppCategoryVO> findVOByParentId(Long parentId) {

        List<AppCategory> list = this.findByParentId(parentId);

        //封装数据
        List<AppCategoryVO> appCategoryVOList = new ArrayList<>();
        for (AppCategory category : list) {
            appCategoryVOList.add(new AppCategoryVO(category.getId(),category.getCategoryName()));
        }
        return appCategoryVOList;
    }

    /**
     * 通过父节点id查询全部子节点的信息 并封装为vo返回
     * @param id
     * @return
     */
    @Override
    public List<EasyUITreeVO> findTreeVOByParentId(Long id) {

        List<AppCategory> categoryList = this.findByParentId(id);

        List<EasyUITreeVO> voList = new ArrayList<>();

        for (AppCategory appCategory : categoryList) {

            EasyUITreeVO easyUITreeVO = new EasyUITreeVO(appCategory.getId(),appCategory.getCategoryName(), AppConstant.IS_PARENT.equals(appCategory.getIsParent())?"closed":"open");
            voList.add(easyUITreeVO);
        }

        return voList;
    }

    @Override
    public List<AppCategory> findByParentId(Long parentId) {
        AppCategory appCategory = new AppCategory();
        appCategory.setParentId(parentId);

        List<AppCategory> list = appCategoryMapper.select(appCategory);
        if (list==null|| list.size()==0){
            log.error("【查询分级目录】 通过父类id查询分级目录失败 该父类不存在子类目录！ parentId={} ",parentId);
//            throw new AppException(AppEnum.SELECT_APPCATEGORY_ERROR.getCode(),"目录暂时为空！");
        }
        return list;
    }


    /**
     * 添加app分类信息
     *   业务逻辑：
     *      1.将接受到的appCategory添加到数据库中，并将添加后的自增主键值返回给面
     *      2.查询该分类的父类节点是否为父节点？（结束）：（修改父节点的isParent属性为1）
     * @param appCategory
     */
    @Override
    @Transactional
    public void addParentIdAndCategoryName(AppCategory appCategory) {

        appCategory.setIsParent(AppConstant.NOT_PARENT);

        int count = appCategoryMapper.insertSelective(appCategory);

        if (count!=1){
            log.error("【添加分类信息】添加分类信息失败！ appCategory={}",appCategory);
            throw new AppException(AppEnum.APPCATEGORY_ADD_ERROR);
        }
        //查询父类节点是否为父节点 如果不是，手动修改为父节点
        AppCategory parentCategory = this.findById(appCategory.getParentId());

        if (AppConstant.NOT_PARENT.equals(parentCategory.getIsParent())){
            parentCategory.setIsParent(AppConstant.IS_PARENT);

            this.updateById(parentCategory);
        }

    }

    @Override
    public AppCategory findById(Long id) {

        AppCategory appCategory = appCategoryMapper.selectByPrimaryKey(id);
        if (appCategory==null){
            log.info("【添加分类信息】查询指定id的分类信息失败！ id={}",id);
            throw new AppException(AppEnum.SELECT_APPCATEGORY_ERROR);
        }

        return appCategory;
    }

    /**
     * 通过id修改app分类信息
     *
     * @param appCategory
     */
    @Override
    @Transactional
    public void updateById(AppCategory appCategory) {

        appCategory.setUpdated(new Date());

        int count = appCategoryMapper.updateByPrimaryKeySelective(appCategory);
        if (count!=1){
            log.info("【修改分类信息】修改指定id的分类信息失败！ appCategory={}",appCategory);
            throw new AppException(AppEnum.APPCATEGORY_UPDATE_ERROR);
        }

    }

    /**
     * 删除指定分类节点的全部分类信息
     * 业务逻辑：
     *      1.查询该节点是否为父节点？（调用递归删除全部子节点然后删除自身）：（直接删除自身）
     *      2.查询该节点的父节点是否有其他子节点？（直接结束）：（修改父节点为叶子节点）
     * @param id
     */
    @Override
    @Transactional
    public void deleteAllById(Long id) {

        AppCategory appCategory = this.findById(id);

        if (AppConstant.IS_PARENT.equals(appCategory.getIsParent())){
            //如果要删除的节点为父节点时  调用递归删除
            this.recursionDelete(appCategory);
        }
        //删除自身节点
        this.deleteById(id);

        List<AppCategory> parentList = this.findByParentId(appCategory.getParentId());

        if (parentList!=null && parentList.size()==0){
            //需要将该节点的父类节点转换为  叶子节点
            AppCategory parentCategory = new AppCategory();
            parentCategory.setId(appCategory.getParentId());
            parentCategory.setUpdated(new Date());
            parentCategory.setIsParent(AppConstant.NOT_PARENT);

            this.updateById(parentCategory);
        }


    }

    @Override
    @Transactional
    public void deleteById(Long id) {
        int count = appCategoryMapper.deleteByPrimaryKey(id);
        if (count!=1){
            log.info("【删除分类信息】删除指定id的分类信息失败！ id={}",id);
            throw new AppException(AppEnum.APPCATEGORY_DELETE_ERROR);
        }
    }

    //递归删除指定节点下的全部分类信息
    private void recursionDelete(AppCategory appCategory){
        //查询该父节点下的全部子节点
        List<AppCategory> sonList = this.findByParentId(appCategory.getId());
        //循环遍历全部子节点
        for (AppCategory category : sonList) {
            //如果子节点还是父节点  继续调用递归删除
            if (AppConstant.IS_PARENT.equals(category.getIsParent())){
                this.recursionDelete(category);
            }
            //无论是什么情况都要删除自身
            this.deleteById(category.getId());

        }


    }

}
